import { Plugin, PluginKey } from 'prosemirror-state'
import { Decoration, DecorationSet } from 'prosemirror-view'
import type { Editor } from '@tiptap/core'
import { useCopilotContext } from '@/ai/AiEditor'
import api from '@/api'
import { createTiptapMarkdownParser } from '@/tiptap/extensions/tiptapMarkdownParser'

export const SuggestionPluginKey = new PluginKey('copilot-suggestion')

let abortController: AbortController | null = null

function removeDuplicatePrefix(original: string, suggestion: string): string {
  let i = 0
  while (i < original.length && i < suggestion.length && original[i] === suggestion[i]) {
    i++
  }
  return suggestion.slice(i)
}

// 包装 AI 请求函数，支持中断控制
export function createRequestAI(editor: Editor) {
  const { getContextMessages } = useCopilotContext({ editor })

  return async () => {
    // 中止上一个请求
    if (abortController) {
      abortController.abort()
    }

    abortController = new AbortController()
    const signal = abortController.signal

    try {
      const messages = getContextMessages()
      console.log('AI 请求消息:', messages)

      // 注意：确保你在 api.aiSuggestion 内支持 { signal }
      const res = await api.aiSuggestion(messages, { signal })

      const data = res.data
      return data?.choices?.[0]?.message?.content?.trim() || ''
    } catch (e: any) {
      if (e.name === 'AbortError') {
        console.warn('[AI 请求被中止]')
      } else {
        console.warn('AI 请求失败:', e)
      }
      return ''
    }
  }
}

export function SuggestionPlugin(editor: Editor, RequestAI: () => Promise<string>) {
  let timeout: number | undefined
  let lastText = ''
  let lastSuggestion = ''
  let requestVersion = 0 // 每次触发请求自增，用于识别过期响应

  async function triggerSuggestion(view) {
    const currentVersion = ++requestVersion // 更新版本号
    const fullText = view.state.doc.textBetween(0, view.state.doc.content.size, '\n')
    lastText = fullText

    try {
      const suggestion = await RequestAI()

      // 忽略过期响应
      if (currentVersion !== requestVersion) {
        console.warn('[忽略过期的 AI 响应]')
        return
      }

      const cleanSuggestion = removeDuplicatePrefix(lastText, suggestion)
      lastSuggestion = cleanSuggestion

      const deco = Decoration.widget(view.state.selection.to, () => {
        const span = document.createElement('span')
        span.className = 'copilot-suggestion'
        span.style.color = 'red'
        span.style.fontStyle = 'italic'
        span.style.whiteSpace = 'pre-wrap'
        span.textContent = cleanSuggestion
        return span
      }, { side: 1 })

      const decorationSet = DecorationSet.create(view.state.doc, [deco])

      view.dispatch(
        view.state.tr.setMeta(SuggestionPluginKey, {
          decorationSet
        }).scrollIntoView()
      )
    } catch (e) {
      console.warn('AI suggestion error:', e)
    }
  }

  return new Plugin({
    key: SuggestionPluginKey,

    state: {
      init() {
        return DecorationSet.empty
      },
      apply(tr, old) {
        const meta = tr.getMeta(SuggestionPluginKey)
        if (meta && meta.decorationSet) {
          return meta.decorationSet
        }
        return old.map(tr.mapping, tr.doc)
      }
    },

    props: {
      decorations(state) {
        return this.getState(state)
      },

      handleTextInput(view, from, to, text) {
        if (timeout) clearTimeout(timeout)
        timeout = setTimeout(() => triggerSuggestion(view), 1000)
        return false
      },

      handleDOMEvents: {
        keydown(view, event) {
          if (event.key === 'Enter' || event.key === 'Backspace') {
            console.log('[DOMEvents] 捕获回车/删除:', event.key)

            view.dispatch(
              view.state.tr.setMeta(SuggestionPluginKey, {
                decorationSet: DecorationSet.empty
              }).scrollIntoView()
            )

            lastSuggestion = ''
            if (timeout) clearTimeout(timeout)
            if (abortController) abortController.abort()
            lastText = view.state.doc.textBetween(0, view.state.doc.content.size, '\n')
            document.querySelectorAll('.copilot-suggestion')?.forEach(e => e.remove())

            return false
          }

          return false
        },

        compositionend(view, event) {
          if (timeout) clearTimeout(timeout)
          timeout = setTimeout(() => triggerSuggestion(view), 2000)
          return false
        }
      },

handleKeyDown(view, event) {
  if (event.key === 'Tab') {
    const { state, dispatch } = view
    const { from, to } = state.selection
    const $from = state.selection.$from
    const node = $from.parent

    if (lastSuggestion) {
      try {
        const parser = createTiptapMarkdownParser(editor.schema)
        const docNode = parser.parse(lastSuggestion)

        if (docNode.content.childCount === 0) {
          console.warn('AI 返回内容为空，无法插入')
          return true
        }

        editor.commands.insertContent(docNode.toJSON())
      } catch (err) {
        console.warn('Markdown 插入失败:', err)
      }

      lastSuggestion = ''
      event.preventDefault()
      return true
    }
    return false
  }
}



    },

    view() {
      return {
        update(view, prevState) {
          const oldText = prevState.doc.textBetween(0, prevState.doc.content.size, '\n')
          const newText = view.state.doc.textBetween(0, view.state.doc.content.size, '\n')

          if (oldText === newText || lastSuggestion === '') return

          const oldTrimmed = oldText.trim()
          const newTrimmed = newText.trim()

          if (oldTrimmed === newTrimmed && newText.length > oldText.length) {
            return
          }

          console.log('Text changed, triggering suggestion...')

          view.dispatch(
            view.state.tr.setMeta(SuggestionPluginKey, {
              decorationSet: DecorationSet.empty
            }).scrollIntoView()
          )

          lastSuggestion = ''
          if (timeout) clearTimeout(timeout)
          if (abortController) abortController.abort()

          timeout = setTimeout(() => triggerSuggestion(view), 2000)
        }
      }
    }
  })
}
